﻿using Kingdee.BOS;
using Kingdee.BOS.App.Data;
using Kingdee.BOS.BusinessEntity.CloudPlatform;
using Kingdee.BOS.BusinessEntity.YunZhiJia;
using Kingdee.BOS.Core.Bill;
using Kingdee.BOS.Core.DynamicForm;
using Kingdee.BOS.Core.Import;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.Core.NotePrint;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.ServiceHelper;
using Kingdee.BOS.Util;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace TZ.PlugIn.FileSrv
{
    public class Common
    {
        private const string Dash = "--";
        private static string Boundary = GenerateBoundary();
        private const string NewLine = "\r\n";
        private const string DefaultContentType = "application/octet-stream";
        /// <summary>
        /// 文件上传Url
        /// </summary>
        public static string UploadFileUrl = "";//文件上传Url
        /// <summary>
        /// 创建电子签约Url
        /// </summary>
        public static string CreateBillUrl = "";//创建电子签约Url
        /// <summary>
        /// 查看电子签约Url
        /// </summary>
        public static string ViewBillUrl = "";//查看电子签约Url
        /// <summary>
        /// 下载签署文档Url
        /// </summary>
        public static string DownloadUrl = "";//下载签署文档Url
        /// <summary>
        /// 是否启用静默签署
        /// </summary>
        public static string SignByCompany = "1";//是否启用静默签署
        /// <summary>
        /// 印章静默签署Url
        /// </summary>
        public static string SignByCpyUrl = "";//印章静默签署Url
        /// <summary>
        /// 撤回电子签约Url
        /// </summary>
        public static string RecallBillUrl = "";//撤回电子签约Url
        /// <summary>
        /// 发起作废签约Url
        /// </summary>
        public static string CancelBillUrl = "";//发起作废签约Url
        /// <summary>
        /// 应用ID
        /// </summary>
        public static string AppToken = "";//应用ID
        /// <summary>
        /// 应用密钥
        /// </summary>
        public static string AppSecret = "";//应用密钥
        /// <summary>
        /// 采购订单套打模板Id
        /// </summary>
        public static string POTemplateId = "";//采购订单套打模板Id

        /// <summary>
        /// 生成导出文件
        /// </summary>
        /// <param name="ctx">链接</param>
        /// <param name="formId">窗体Id</param>
        /// <param name="billId">单据内码</param>
        /// <param name="templateId">套打模板Id</param>
        /// <returns></returns>
        public static ExportFileInfo GetExportFile(Context ctx, string formId, string billId, string templateId)
        {
            return ExportTargetBill(ctx, formId, billId, templateId);
        }

        /// <summary>
        /// 套打导出指定单据
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="formId"></param>
        /// <param name="billId"></param>
        /// <param name="templateId"></param>
        /// <returns></returns>
        public static ExportFileInfo ExportTargetBill(Context ctx, string formId, string billId, string templateId)
        {
            IDynamicFormView dynamicFormView = CreateBillView(ctx, formId, billId); //此行为代码模拟打开凭证界面
            if (dynamicFormView == null)
                return null;
            IImportView billView = dynamicFormView as IImportView;
            if (billView != null)
            {
                billView.AddViewSession();
            }
            try
            {
                return ExportTargetBillWithDynamic(dynamicFormView, formId, billId, templateId);
            }
            finally
            {
                if (billView != null)
                {
                    billView.RemoveViewSession();
                }
                dynamicFormView.Close();
            }
        }

        public static ExportFileInfo ExportTargetBillWithDynamic(IDynamicFormView dynamicFormView, string formId, string billId, string templateId)
        {
            IDynamicFormViewService viewService = dynamicFormView as IDynamicFormViewService;
            if (viewService == null)
                return null;
            List<string> billIds = new List<string>() { billId };
            List<string> templateIds = new List<string>() { templateId };

            PrintExportInfo pExInfo = new PrintExportInfo();
            pExInfo.PageId = dynamicFormView.PageId;
            pExInfo.FormId = formId;
            pExInfo.BillIds = billIds; //单据内码
            pExInfo.TemplateIds = templateIds; //套打模板ID
            pExInfo.FileType = ExportFileType.PDF; //文件格式
            pExInfo.ExportType = ExportType.BillTempId; //导出格式
            string fileName = Guid.NewGuid().ToString() + ".PDF";
            string temppath = PathUtils.GetPhysicalPath("TempfilePath", fileName);
            pExInfo.FilePath = temppath; //文件输出路径

            //指定动态文件目录和动态文件名
            pExInfo.ExportDynamicDirectory = pExInfo.Id;
            pExInfo.ExportDynamicFileName = "{FBillNo}";
            viewService.ExportNotePrint(pExInfo);

            if (pExInfo.ExportFileInfos == null || pExInfo.ExportFileInfos.Count <= 0)
                return null;
            return pExInfo.ExportFileInfos[0];
        }

        /// <summary>
        /// 构建表单打开参数
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="metadata"></param>
        /// <param name="pkValue"></param>
        /// <returns></returns>
        private static BillOpenParameter CreateOpenParameter(Context ctx, FormMetadata metadata, string pkValue)
        {
            var form = metadata.BusinessInfo.GetForm();
            BillOpenParameter openPara = new BillOpenParameter(form.Id, metadata.GetLayoutInfo().Id);
            openPara.Context = ctx;
            openPara.PageId = Guid.NewGuid().ToString();
            openPara.Status = OperationStatus.VIEW;
            openPara.CreateFrom = CreateFrom.Default;
            openPara.DefaultBillTypeId = string.Empty;
            openPara.PkValue = pkValue;
            openPara.FormMetaData = metadata;
            openPara.SetCustomParameter(Kingdee.BOS.Core.FormConst.PlugIns, form.CreateFormPlugIns());
            openPara.ServiceName = form.FormServiceName;
            return openPara;
        }

        /// <summary>
        /// 创建视图
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="formId"></param>
        /// <param name="pkValue"></param>
        /// <returns></returns>
        public static IDynamicFormView CreateBillView(Context ctx, string formId, string pkValue)
        {
            FormMetadata metadata = MetaDataServiceHelper.Load(ctx, formId) as FormMetadata;
            if (metadata == null)
                return null;
            var openParameter = CreateOpenParameter(ctx, metadata, pkValue);
            var provider = metadata.BusinessInfo.GetForm().GetFormServiceProvider();

            string importViewClass = "Kingdee.BOS.Web.Import.ImportBillView,Kingdee.BOS.Web";
            Type type = Type.GetType(importViewClass);
            IDynamicFormViewService billView = (IDynamicFormViewService)Activator.CreateInstance(type);
            billView.Initialize(openParameter, provider);
            billView.LoadData();
            return (IDynamicFormView)billView;
        }

        public static void GetParams(Context ctx)
        {
            var sql = string.Format(@"/*dialect*/select * from QYS_InterfaceSet order by ID");
            DynamicObjectCollection dySet = DBUtils.ExecuteDynamicObject(ctx, sql);
            foreach (var dy in dySet)
            {
                if (dy["DataType"].ToString() == "UploadFileUrl")
                    UploadFileUrl = dy["DataValue"].ToString();
                if (dy["DataType"].ToString() == "CreateBillUrl")
                    CreateBillUrl = dy["DataValue"].ToString();
                if (dy["DataType"].ToString() == "ViewBillUrl")
                    ViewBillUrl = dy["DataValue"].ToString();
                if (dy["DataType"].ToString() == "DownloadUrl")
                    DownloadUrl = dy["DataValue"].ToString();
                if (dy["DataType"].ToString() == "SignByCompany")
                    SignByCompany = dy["DataValue"].ToString();
                if (dy["DataType"].ToString() == "SignByCpyUrl")
                    SignByCpyUrl = dy["DataValue"].ToString();
                if (dy["DataType"].ToString() == "RecallBillUrl")
                    RecallBillUrl = dy["DataValue"].ToString();
                if (dy["DataType"].ToString() == "CancelBillUrl")
                    CancelBillUrl = dy["DataValue"].ToString();
                if (dy["DataType"].ToString() == "AppToken")
                    AppToken = dy["DataValue"].ToString();
                if (dy["DataType"].ToString() == "AppSecret")
                    AppSecret = dy["DataValue"].ToString();
                if (dy["DataType"].ToString() == "POTemplateId")
                    POTemplateId = dy["DataValue"].ToString();
            }
        }

        private static long GetTimeStamp()
        {
            return Convert.ToInt64((DateTime.Now.ToUniversalTime() - DateTime.Parse("1970-1-1")).TotalMilliseconds);
        }

        private static string Md5(string appToken, string appSecret, string timestamp)
        {
            var unEncryted = appToken + appSecret + timestamp;

            var result = string.Empty;
            if (string.IsNullOrEmpty(unEncryted))
            {
                return result;
            }

            using (var md5 = MD5.Create())
            {
                result = GetMd5Hash(md5, unEncryted);
            }
            return result;
        }

        private static string GetMd5Hash(MD5 md5Hash, string input)
        {
            byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));
            var sBuilder = new StringBuilder();
            foreach (byte t in data)
            {
                sBuilder.Append(t.ToString("x2"));
            }
            return sBuilder.ToString();
        }

        private static string GenerateBoundary()
        {
            return "----" + Guid.NewGuid().ToString("N");
        }

        private static void WriteMultipart(ref Stream stream, string name, string value)
        {
            StringBuilder content = new StringBuilder().Append(Dash).Append(Boundary).Append(NewLine)
                .Append("Content-Disposition: form-data; name=").Append(name).Append(NewLine)
                .Append("Content-Type: text/plain; charset=utf-8").Append(NewLine)
                .Append(NewLine)
                .Append(value).Append(NewLine);

            Byte[] data = Encoding.UTF8.GetBytes(content.ToString());
            stream.Write(data, 0, data.Length);
        }

        private static void WriteMultipart(ref Stream stream, string name, int value)
        {
            WriteMultipart(ref stream, name, value.ToString());
        }

        private static void WriteMultipart(ref Stream stream, string name, long value)
        {
            WriteMultipart(ref stream, name, value.ToString());
        }

        private static void WriteMultipart(ref Stream stream, string name, float value)
        {
            WriteMultipart(ref stream, name, value.ToString());
        }

        private static void WriteMultipart(ref Stream stream, string name, double value)
        {
            WriteMultipart(ref stream, name, value.ToString());
        }

        private static void WriteMultipart(ref Stream stream, string name, bool value)
        {
            WriteMultipart(ref stream, name, value ? "true" : "false");
        }

        private static void WriteMultipart(ref Stream stream, string name, FileInfo fileInfo)
        {
            WriteMultipart(ref stream, name, null, null, fileInfo);
        }

        private static void WriteMultipart(ref Stream stream, string name, string filename, string contentType, FileInfo fileInfo)
        {
            filename = string.IsNullOrWhiteSpace(filename) ? fileInfo.Name : filename;
            String encodedFilename = UrlEncodeUTF8(filename);

            StringBuilder header = new StringBuilder().Append(Dash).Append(Boundary).Append(NewLine)
                    .Append("Content-Disposition: form-data; name=").Append(name).Append("; filename=").Append(encodedFilename).Append(NewLine)
                    .Append("Content-Type:").Append(string.IsNullOrWhiteSpace(contentType) ? DefaultContentType : contentType).Append(NewLine)
                    .Append(NewLine);
            Byte[] data = Encoding.UTF8.GetBytes(header.ToString());
            stream.Write(data, 0, data.Length);

            byte[] buffer = new byte[8096];

            FileStream fileStream = null;

            try
            {
                fileStream = fileInfo.OpenRead();

                int count;
                while ((count = fileStream.Read(buffer, 0, buffer.Length)) != 0)
                {
                    stream.Write(buffer, 0, count);
                }
                data = Encoding.UTF8.GetBytes(NewLine);
                stream.Write(data, 0, data.Length);
            }
            catch (Exception ex)
            {
                // 异常处理
                var MsgErr = ex.Message;
            }
            finally
            {
                if (fileStream != null)
                {
                    fileStream.Close();
                }
            }
        }

        private static string UrlEncodeUTF8(string source)
        {
            return HttpUtility.UrlEncode(source, System.Text.Encoding.UTF8);
        }

        /// <summary>
        /// 上传文件创建电子签约
        /// </summary>
        /// <param name="Url"></param>
        /// <param name="AppToken"></param>
        /// <param name="AppSecret"></param>
        /// <param name="FilePath"></param>
        /// <param name="FileTitle"></param>
        /// <param name="isSuccess"></param>
        /// <returns></returns>
        public static object PostFile(string Url, string AppToken, string AppSecret, string FilePath, string FileTitle, string supName, ref bool isSuccess)
        {
            HttpWebRequest httpRequest = null;
            Stream stream = null;
            long timestamp = GetTimeStamp();

            try
            {
                httpRequest = (HttpWebRequest)WebRequest.Create(Url);
                httpRequest.Method = "POST";
                httpRequest.Accept = "text/plain,application/json";
                httpRequest.UserAgent = "privateapp-csharp-api-client";
                //httpRequest.Headers.Add("Host", GetHost(Url));
                httpRequest.Headers.Add("x-qys-accesstoken", AppToken);
                httpRequest.Headers.Add("x-qys-timestamp", timestamp.ToString());
                httpRequest.Headers.Add("x-qys-signature", Md5(AppToken, AppSecret, timestamp.ToString()));
                httpRequest.ContentType = "multipart/form-data; boundary=" + Boundary;
                //httpRequest.Headers.Add("Transfer-Encoding", "chunked");
                httpRequest.SendChunked = true;

                stream = httpRequest.GetRequestStream();

                WriteMultipart(ref stream, "title", FileTitle + "-" + supName);
                WriteMultipart(ref stream, "fileType", "pdf");
                WriteMultipart(ref stream, "file", new FileInfo(FilePath));

                Byte[] data = Encoding.UTF8.GetBytes(new StringBuilder().Append(Dash).Append(Boundary).Append(Dash).Append(NewLine).ToString());
                stream.Write(data, 0, data.Length);
                stream.Flush();

                HttpWebResponse response = (HttpWebResponse)httpRequest.GetResponse();
                if ((int)response.StatusCode == 200)
                {
                    StreamReader returnStream = null;
                    try
                    {
                        returnStream = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
                        var result = returnStream.ReadToEnd();
                        var ReturnMsg = JObject.Parse(result);
                        isSuccess = true;
                        return ReturnMsg;
                    }
                    catch (Exception ex)
                    {
                        isSuccess = false;
                        return ex.Message;
                    }
                    finally
                    {
                        if (returnStream != null)
                            returnStream.Close();
                    }
                }
                else
                {
                    isSuccess = false;
                    var retString = "【" + ((int)response.StatusCode).ToString() + "】:" + response.StatusDescription;
                    return retString;
                }
            }
            catch (Exception ex)
            {
                isSuccess = false;
                return ex.Message;
            }
            finally
            {
                if (stream != null)
                    stream.Close();
            }
        }

        /// <summary>
        /// 创建电子签约单
        /// </summary>
        /// <param name="Url"></param>
        /// <param name="AppToken"></param>
        /// <param name="AppSecret"></param>
        /// <param name="JsonData"></param>
        /// <param name="isSuccess"></param>
        /// <returns></returns>
        public static object PostBill(string Url, string AppToken, string AppSecret, object JsonData, ref bool isSuccess)
        {
            long timestamp = GetTimeStamp();
            Stream reqStream = null;

            try
            {
                string body = JsonConvert.SerializeObject(JsonData);
                var dataEncode = Encoding.UTF8;
                byte[] byteArray = dataEncode.GetBytes(body); //转化
                var request = (HttpWebRequest)WebRequest.Create(Url);
                request.Method = "POST";
                request.ContentType = "application/json";
                request.Headers.Add("x-qys-signature", Md5(AppToken, AppSecret, timestamp.ToString()));
                request.Headers.Add("x-qys-timestamp", timestamp.ToString());
                request.Headers.Add("x-qys-accesstoken", AppToken);
                request.ContentLength = byteArray.Length;
                request.Timeout = -1;

                reqStream = request.GetRequestStream();
                reqStream.Write(byteArray, 0, byteArray.Length);
                reqStream.Flush();

                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                if ((int)response.StatusCode == 200)
                {
                    StreamReader returnStream = null;
                    try
                    {
                        returnStream = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
                        var result = returnStream.ReadToEnd();
                        var ReturnMsg = JObject.Parse(result);
                        isSuccess = true;
                        return ReturnMsg;
                    }
                    catch (Exception ex)
                    {
                        isSuccess = false;
                        return ex.Message;
                    }
                    finally
                    {
                        if (returnStream != null)
                            returnStream.Close();
                    }
                }
                else
                {
                    isSuccess = false;
                    var retString = "【" + ((int)response.StatusCode).ToString() + "】:" + response.StatusDescription;
                    return retString;
                }
            }
            catch (Exception ex)
            {
                isSuccess = false;
                return ex.Message;
            }
            finally
            {
                if (reqStream != null)
                    reqStream.Close();
            }
        }

        /// <summary>
        /// 创建电子签约报文 我方签
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="dycoll"></param>
        /// <returns></returns>
        public static object GetPurJsonData1(Context ctx, DynamicObjectCollection dycoll, string pKID, DynamicObjectCollection mailList, string fEMail, string fEMai2, string contact, string billNo, string supName)
        {
            var BillNo = dycoll[0]["BillNo"].ToString();
            JObject JsonRoot = new JObject();
            //JsonRoot.Add("subject", dycoll[0]["subject"].ToString());
            JsonRoot.Add("subject", billNo + "-" + supName);
            JsonRoot.Add("sn", pKID);
            JsonRoot.Add("bizId", "");
            JsonRoot.Add("categoryId", dycoll[0]["CategoryId"].ToString());
            Int64 DocumentId = Convert.ToInt64(dycoll[0]["DocumentId"].ToString());
            List<Int64> documents = new List<Int64> { DocumentId };
            JsonRoot.Add("documents", JsonConvert.DeserializeObject(JsonConvert.SerializeObject(documents)) as JToken);
            JsonRoot.Add("tenantName", dycoll[0]["TenanName"].ToString());
            JObject creatorInfo = new JObject();
            creatorInfo.Add("number", dycoll[0]["creatorInfo"].ToString());
            JsonRoot.Add("creatorInfo", creatorInfo);

            JArray transmitters = new JArray();
            if (mailList.Count > 0)
            {
                foreach (var mail in mailList)
                {
                    JObject email = new JObject();//接收邮件
                    email.Add("receiverName", mail[0].ToString());
                    email.Add("receiverMobile", mail[1].ToString());
                    if (!mail[0].ToString().IsNullOrEmptyOrWhiteSpace() && !mail[1].ToString().IsNullOrEmptyOrWhiteSpace())
                    {
                        transmitters.Add(email);
                    }
                }
            }

            JObject email2 = new JObject();//接收邮件
            email2.Add("receiverName", contact);
            email2.Add("receiverMobile", fEMail);
            if (!contact.IsNullOrEmptyOrWhiteSpace() && !fEMail.IsNullOrEmptyOrWhiteSpace())
            {
                transmitters.Add(email2);
            }
            JObject email3 = new JObject();//接收邮件
            email3.Add("receiverName", contact);
            email3.Add("receiverMobile", fEMai2);
            if (!contact.IsNullOrEmptyOrWhiteSpace() && !fEMai2.IsNullOrEmptyOrWhiteSpace())
            {
                transmitters.Add(email3);
            }

            JsonRoot.Add("transmitters", transmitters);

            JArray signatories = new JArray();
            JObject signatorie1 = new JObject();//发起方主体

            signatorie1.Add("tenantType", dycoll[0]["signatorie_1_tenantType"].ToString());
            signatorie1.Add("tenantName", dycoll[0]["signatorie_1_tenantName"].ToString());
            signatorie1.Add("serialNo", dycoll[0]["signatorie_1_serialNo"].ToString());
            JArray actions_1 = new JArray();
            JObject action_1 = new JObject();
            action_1.Add("type", dycoll[0]["signatorie_1_actions_type"].ToString());
            action_1.Add("name", dycoll[0]["signatorie_1_actions_name"].ToString());
            action_1.Add("serialNo", dycoll[0]["signatorie_1_actions_serialNo"].ToString());
            action_1.Add("sealCategoryName", dycoll[0]["signatorie_1_actions_sealCategoryName"].ToString());
            JArray locations_1 = new JArray();

            JObject location_1 = new JObject();
            location_1.Add("rectType", dycoll[0]["signatorie_1_actions_locations_1_rectType"].ToString());
            location_1.Add("keyword", dycoll[0]["signatorie_1_actions_locations_1_keyword"].ToString());
            location_1.Add("relativePosition", dycoll[0]["signatorie_1_actions_locations_1_relativePosition"].ToString());
            location_1.Add("keywordIndex", "0");

            JObject location_2 = new JObject();
            location_2.Add("rectType", dycoll[0]["signatorie_1_actions_locations_2_rectType"].ToString());
            location_2.Add("offsetY", Convert.ToDecimal(dycoll[0]["signatorie_1_actions_locations_2_offsetY"].ToString()));
            location_2.Add("page", Convert.ToInt32(dycoll[0]["signatorie_1_actions_locations_2_page"].ToString()));

            locations_1.Add(location_1);
            locations_1.Add(location_2);
            action_1.Add("locations", locations_1);
            actions_1.Add(action_1);
            signatorie1.Add("actions", actions_1);

            JObject signatorie2 = new JObject();//供应商
            signatorie2.Add("tenantType", dycoll[0]["signatorie_2_tenantType"].ToString());
            signatorie2.Add("tenantName", dycoll[0]["signatorie_2_tenantName"].ToString());
            signatorie2.Add("contact", dycoll[0]["signatorie_2_contact"].ToString());
            signatorie2.Add("serialNo", dycoll[0]["signatorie_2_serialNo"].ToString());
            JArray actions_2 = new JArray();

            JObject action_2_1 = new JObject();
            action_2_1.Add("type", dycoll[0]["signatorie_2_actions_1_type"].ToString());
            action_2_1.Add("name", dycoll[0]["signatorie_2_actions_1_name"].ToString());
            action_2_1.Add("serialNo", dycoll[0]["signatorie_2_actions_1_serialNo"].ToString());
            JArray locations_2_1 = new JArray();
            JObject location_2_1 = new JObject();
            location_2_1.Add("rectType", dycoll[0]["signatorie_2_actions_1_locations_rectType"].ToString());
            location_2_1.Add("keyword", dycoll[0]["signatorie_2_actions_1_locations_keyword"].ToString());
            location_2_1.Add("relativePosition", dycoll[0]["signatorie_2_actions_1_locations_relativePosition"].ToString());
            locations_2_1.Add(location_2_1);
            action_2_1.Add("locations", locations_2_1);

            JObject action_2_2 = new JObject();
            action_2_2.Add("type", dycoll[0]["signatorie_2_actions_2_type"].ToString());
            action_2_2.Add("name", dycoll[0]["signatorie_2_actions_2_name"].ToString());
            action_2_2.Add("serialNo", dycoll[0]["signatorie_2_actions_2_serialNo"].ToString());
            JArray locations_2_2 = new JArray();
            JObject location_2_2_1 = new JObject();
            location_2_2_1.Add("rectType", dycoll[0]["signatorie_2_actions_2_locations_1_rectType"].ToString());
            location_2_2_1.Add("keyword", dycoll[0]["signatorie_2_actions_2_locations_1_keyword"].ToString());
            location_2_2_1.Add("relativePosition", dycoll[0]["signatorie_2_actions_2_locations_1_relativePosition"].ToString());

            JObject location_2_2_2 = new JObject();
            location_2_2_2.Add("rectType", dycoll[0]["signatorie_2_actions_2_locations_2_rectType"].ToString());
            location_2_2_2.Add("offsetY", Convert.ToDecimal(dycoll[0]["signatorie_2_actions_2_locations_2_offsetY"].ToString()));
            location_2_2_2.Add("page", Convert.ToInt32(dycoll[0]["signatorie_2_actions_2_locations_2_page"].ToString()));

            locations_2_2.Add(location_2_2_1);
            locations_2_2.Add(location_2_2_2);
            action_2_2.Add("locations", locations_2_2);

            actions_2.Add(action_2_1);
            actions_2.Add(action_2_2);
            signatorie2.Add("actions", actions_2);

            signatories.Add(signatorie1);
            //signatories.Add(signatorie2);
            JsonRoot.Add("signatories", signatories);

            Common.CreateJsonLog(ctx, "采购订单同步契约锁", BillNo, JsonRoot.ToString(), "");
            return JsonRoot;
        }

        /// <summary>
        /// 创建电子签约报文 双方签
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="dycoll"></param>
        /// <returns></returns>
        public static object GetPurJsonData(Context ctx, DynamicObjectCollection dycoll, string providerPhone, string pKID, DynamicObjectCollection mailList, string contact, string fEMail, string fEMai2, string billNo, string supName)
        {
            var BillNo = dycoll[0]["BillNo"].ToString();
            JObject JsonRoot = new JObject();
            //JsonRoot.Add("subject", dycoll[0]["subject"].ToString());
            JsonRoot.Add("subject", billNo + "-" + supName);
            JsonRoot.Add("sn", pKID);
            JsonRoot.Add("bizId", "");
            JsonRoot.Add("categoryId", dycoll[0]["CategoryId"].ToString());
            Int64 DocumentId = Convert.ToInt64(dycoll[0]["DocumentId"].ToString());
            List<Int64> documents = new List<Int64> { DocumentId };
            JsonRoot.Add("documents", JsonConvert.DeserializeObject(JsonConvert.SerializeObject(documents)) as JToken);
            JsonRoot.Add("tenantName", dycoll[0]["TenanName"].ToString());
            JObject creatorInfo = new JObject();
            creatorInfo.Add("number", dycoll[0]["creatorInfo"].ToString());
            JsonRoot.Add("creatorInfo", creatorInfo);

            JArray transmitters = new JArray();
            if (mailList.Count > 0)
            {
                foreach (var mail in mailList)
                {
                    JObject email = new JObject();//接收邮件
                    email.Add("receiverName", mail[0].ToString());
                    email.Add("receiverMobile", mail[1].ToString());
                    if (!mail[0].ToString().IsNullOrEmptyOrWhiteSpace() && !mail[1].ToString().IsNullOrEmptyOrWhiteSpace())
                    {
                        transmitters.Add(email);
                    }
                }
            }
            JObject email2 = new JObject();//接收邮件
            email2.Add("receiverName", contact);
            email2.Add("receiverMobile", fEMail);
            if (!contact.IsNullOrEmptyOrWhiteSpace() && !fEMail.IsNullOrEmptyOrWhiteSpace())
            {
                transmitters.Add(email2);
            }
            JObject email3 = new JObject();//接收邮件
            email3.Add("receiverName", contact);
            email3.Add("receiverMobile", fEMai2);
            if (!contact.IsNullOrEmptyOrWhiteSpace() && !fEMai2.IsNullOrEmptyOrWhiteSpace())
            {
                transmitters.Add(email3);
            }
            JsonRoot.Add("transmitters", transmitters);

            JArray signatories = new JArray();
            JObject signatorie1 = new JObject();//发起方主体

            signatorie1.Add("tenantType", dycoll[0]["signatorie_1_tenantType"].ToString());
            signatorie1.Add("tenantName", dycoll[0]["signatorie_1_tenantName"].ToString());
            signatorie1.Add("serialNo", dycoll[0]["signatorie_1_serialNo"].ToString());
            JArray actions_1 = new JArray();
            JObject action_1 = new JObject();
            action_1.Add("type", dycoll[0]["signatorie_1_actions_type"].ToString());
            action_1.Add("name", dycoll[0]["signatorie_1_actions_name"].ToString());
            action_1.Add("serialNo", dycoll[0]["signatorie_1_actions_serialNo"].ToString());
            action_1.Add("sealCategoryName", dycoll[0]["signatorie_1_actions_sealCategoryName"].ToString());
            JArray locations_1 = new JArray();

            JObject location_1 = new JObject();
            location_1.Add("rectType", dycoll[0]["signatorie_1_actions_locations_1_rectType"].ToString());
            location_1.Add("keyword", dycoll[0]["signatorie_1_actions_locations_1_keyword"].ToString());
            location_1.Add("relativePosition", dycoll[0]["signatorie_1_actions_locations_1_relativePosition"].ToString());
            location_1.Add("keywordIndex", "0");

            JObject location_2 = new JObject();
            location_2.Add("rectType", dycoll[0]["signatorie_1_actions_locations_2_rectType"].ToString());
            location_2.Add("offsetY", Convert.ToDecimal(dycoll[0]["signatorie_1_actions_locations_2_offsetY"].ToString()));
            location_2.Add("page", Convert.ToInt32(dycoll[0]["signatorie_1_actions_locations_2_page"].ToString()));

            locations_1.Add(location_1);
            locations_1.Add(location_2);
            action_1.Add("locations", locations_1);
            actions_1.Add(action_1);
            signatorie1.Add("actions", actions_1);

            JObject signatorie2 = new JObject();//供应商
            signatorie2.Add("tenantType", dycoll[0]["signatorie_2_tenantType"].ToString());
            signatorie2.Add("tenantName", dycoll[0]["signatorie_2_tenantName"].ToString());
            signatorie2.Add("contact", dycoll[0]["signatorie_2_contact"].ToString());
            signatorie2.Add("serialNo", dycoll[0]["signatorie_2_serialNo"].ToString());
            JArray actions_2 = new JArray();

            JObject action_2_1 = new JObject();
            action_2_1.Add("type", dycoll[0]["signatorie_2_actions_1_type"].ToString());
            action_2_1.Add("name", dycoll[0]["signatorie_2_actions_1_name"].ToString());
            action_2_1.Add("serialNo", dycoll[0]["signatorie_2_actions_1_serialNo"].ToString());

            // 新增 actionOperators 数组
            JArray actionOperators = new JArray();
            JObject operatorContact = new JObject();
            operatorContact.Add("operatorContact", providerPhone);
            actionOperators.Add(operatorContact);
            action_2_1.Add("actionOperators", actionOperators);  // 添加到 action_2_1

            JArray locations_2_1 = new JArray();
            JObject location_2_1 = new JObject();
            location_2_1.Add("rectType", dycoll[0]["signatorie_2_actions_1_locations_rectType"].ToString());
            location_2_1.Add("keyword", dycoll[0]["signatorie_2_actions_1_locations_keyword"].ToString());
            location_2_1.Add("relativePosition", dycoll[0]["signatorie_2_actions_1_locations_relativePosition"].ToString());
            location_2_1.Add("keywordIndex", "0");
            locations_2_1.Add(location_2_1);
            action_2_1.Add("locations", locations_2_1);

            JObject action_2_2 = new JObject();
            action_2_2.Add("type", dycoll[0]["signatorie_2_actions_2_type"].ToString());
            action_2_2.Add("name", dycoll[0]["signatorie_2_actions_2_name"].ToString());
            action_2_2.Add("serialNo", dycoll[0]["signatorie_2_actions_2_serialNo"].ToString());
            JArray locations_2_2 = new JArray();
            JObject location_2_2_1 = new JObject();
            location_2_2_1.Add("rectType", dycoll[0]["signatorie_2_actions_2_locations_1_rectType"].ToString());
            location_2_2_1.Add("keyword", dycoll[0]["signatorie_2_actions_2_locations_1_keyword"].ToString());
            location_2_2_1.Add("relativePosition", dycoll[0]["signatorie_2_actions_2_locations_1_relativePosition"].ToString());

            JObject location_2_2_2 = new JObject();
            location_2_2_2.Add("rectType", dycoll[0]["signatorie_2_actions_2_locations_2_rectType"].ToString());
            location_2_2_2.Add("offsetY", Convert.ToDecimal(dycoll[0]["signatorie_2_actions_2_locations_2_offsetY"].ToString()));
            location_2_2_2.Add("page", Convert.ToInt32(dycoll[0]["signatorie_2_actions_2_locations_2_page"].ToString()));

            locations_2_2.Add(location_2_2_1);
            locations_2_2.Add(location_2_2_2);
            action_2_2.Add("locations", locations_2_2);

            actions_2.Add(action_2_1);
            actions_2.Add(action_2_2);
            signatorie2.Add("actions", actions_2);

            signatories.Add(signatorie1);
            signatories.Add(signatorie2);
            JsonRoot.Add("signatories", signatories);

            Common.CreateJsonLog(ctx, "采购订单同步契约锁", BillNo, JsonRoot.ToString(), "");
            return JsonRoot;
        }

        /// <summary>
        /// 获取电子签约单浏览链接Url
        /// </summary>
        /// <param name="Url"></param>
        /// <param name="AppToken"></param>
        /// <param name="AppSecret"></param>
        /// <param name="isSuccess"></param>
        /// <returns></returns>
        public static object GetView(string Url, string AppToken, string AppSecret, ref bool isSuccess)
        {
            HttpWebRequest httpRequest = null;
            Stream stream = null;
            long timestamp = GetTimeStamp();
            try
            {
                httpRequest = (HttpWebRequest)WebRequest.Create(Url);
                httpRequest.Method = "GET";
                httpRequest.Accept = "text/plain,application/json";
                httpRequest.UserAgent = "privateapp-csharp-api-client";
                httpRequest.Headers.Add("x-qys-accesstoken", AppToken);
                httpRequest.Headers.Add("x-qys-timestamp", timestamp.ToString());
                httpRequest.Headers.Add("x-qys-signature", Md5(AppToken, AppSecret, timestamp.ToString()));

                HttpWebResponse response = (HttpWebResponse)httpRequest.GetResponse();
                if ((int)response.StatusCode == 200)
                {
                    StreamReader returnStream = null;
                    try
                    {
                        returnStream = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
                        var result = returnStream.ReadToEnd();
                        var ReturnMsg = JObject.Parse(result);
                        isSuccess = true;
                        return ReturnMsg;
                    }
                    catch (Exception ex)
                    {
                        isSuccess = false;
                        return ex.Message;
                    }
                    finally
                    {
                        if (returnStream != null)
                            returnStream.Close();
                    }
                }
                else
                {
                    isSuccess = false;
                    var retString = "【" + ((int)response.StatusCode).ToString() + "】:" + response.StatusDescription;
                    return retString;
                }
            }
            catch (Exception ex)
            {
                isSuccess = false;
                return ex.Message;
            }
            finally
            {
                if (stream != null)
                    stream.Close();
            }
        }

        /// <summary>
        /// 下载电子签署文档
        /// </summary>
        /// <param name="Url"></param>
        /// <param name="AppToken"></param>
        /// <param name="AppSecret"></param>
        /// <param name="FilePath"></param>
        /// <param name="isSuccess"></param>
        /// <param name="ErrMsg"></param>
        public static void GetFile(string Url, string AppToken, string AppSecret, string FilePath, ref bool isSuccess, ref string ErrMsg)
        {
            HttpWebRequest httpRequest = null;
            Stream stream = null;
            long timestamp = GetTimeStamp();
            try
            {
                httpRequest = (HttpWebRequest)WebRequest.Create(Url);
                httpRequest.Method = "GET";
                httpRequest.Accept = "text/plain,application/json";
                httpRequest.UserAgent = "privateapp-csharp-api-client";
                httpRequest.Headers.Add("x-qys-accesstoken", AppToken);
                httpRequest.Headers.Add("x-qys-timestamp", timestamp.ToString());
                httpRequest.Headers.Add("x-qys-signature", Md5(AppToken, AppSecret, timestamp.ToString()));

                HttpWebResponse response = (HttpWebResponse)httpRequest.GetResponse();
                if ((int)response.StatusCode == 200)
                {
                    FileStream fs = null;
                    try
                    {
                        stream = response.GetResponseStream();
                        fs = new FileStream(FilePath, FileMode.Create);
                        stream.CopyTo(fs);
                        isSuccess = true;
                        ErrMsg = "";
                    }
                    catch (Exception ex)
                    {
                        isSuccess = false;
                        ErrMsg = ex.Message;
                    }
                    finally
                    {
                        if (fs != null)
                            fs.Close();
                    }
                }
                else
                {
                    isSuccess = false;
                    var retString = "【" + ((int)response.StatusCode).ToString() + "】:" + response.StatusDescription;
                    ErrMsg = retString;
                }
            }
            catch (Exception ex)
            {
                isSuccess = false;
                ErrMsg = ex.Message;
            }
            finally
            {
                if (stream != null)
                    stream.Close();
            }
        }

        /// <summary>
        /// 撤回电子签约单
        /// </summary>
        /// <param name="Url"></param>
        /// <param name="AppToken"></param>
        /// <param name="AppSecret"></param>
        /// <param name="ContractId"></param>
        /// <param name="Reason"></param>
        /// <param name="isSuccess"></param>
        /// <returns></returns>
        public static object PostRecall(string Url, string AppToken, string AppSecret, string ContractId, string Reason, ref bool isSuccess)
        {
            HttpWebRequest httpRequest = null;
            Stream stream = null;
            long timestamp = GetTimeStamp();

            try
            {
                httpRequest = (HttpWebRequest)WebRequest.Create(Url);
                httpRequest.Method = "POST";
                httpRequest.Accept = "text/plain,application/json";
                httpRequest.UserAgent = "privateapp-csharp-api-client";
                httpRequest.Headers.Add("x-qys-accesstoken", AppToken);
                httpRequest.Headers.Add("x-qys-timestamp", timestamp.ToString());
                httpRequest.Headers.Add("x-qys-signature", Md5(AppToken, AppSecret, timestamp.ToString()));
                httpRequest.ContentType = "multipart/form-data; boundary=" + Boundary;
                httpRequest.SendChunked = true;

                stream = httpRequest.GetRequestStream();

                WriteMultipart(ref stream, "contractId", ContractId);
                WriteMultipart(ref stream, "reason", Reason);

                Byte[] data = Encoding.UTF8.GetBytes(new StringBuilder().Append(Dash).Append(Boundary).Append(Dash).Append(NewLine).ToString());
                stream.Write(data, 0, data.Length);
                stream.Flush();

                HttpWebResponse response = (HttpWebResponse)httpRequest.GetResponse();
                if ((int)response.StatusCode == 200)
                {
                    StreamReader returnStream = null;
                    try
                    {
                        returnStream = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
                        var result = returnStream.ReadToEnd();
                        var ReturnMsg = JObject.Parse(result);
                        isSuccess = true;
                        return ReturnMsg;
                    }
                    catch (Exception ex)
                    {
                        isSuccess = false;
                        return ex.Message;
                    }
                    finally
                    {
                        if (returnStream != null)
                            returnStream.Close();
                    }
                }
                else
                {
                    isSuccess = false;
                    var retString = "【" + ((int)response.StatusCode).ToString() + "】:" + response.StatusDescription;
                    return retString;
                }
            }
            catch (Exception ex)
            {
                isSuccess = false;
                return ex.Message;
            }
            finally
            {
                if (stream != null)
                    stream.Close();
            }
        }

        /// <summary>
        /// 创建同步Json日志
        /// </summary>
        /// <param name="ctx">金蝶链接串</param>
        /// <param name="LogType">Json日志类型</param>
        /// <param name="BillNo">单据编号</param>
        /// <param name="JsonText">Json串</param>
        /// <param name="Remark">备注</param>
        public static void CreateJsonLog(Context ctx, string LogType, string BillNo, string JsonText, string Remark)
        {
            var sql = string.Format("exec SP_CreateSynchJsonLog '{0}','{1}','{2}','{3}','{4}'",
                    LogType, BillNo, JsonText, Remark, ctx.UserName
                    );
            DBUtils.Execute(ctx, sql);
        }

        /// <summary>
        /// 上传附件管理Json
        /// </summary>
        /// <param name="FileName"></param>
        /// <param name="FormId"></param>
        /// <param name="IsLast"></param>
        /// <param name="InterId"></param>
        /// <param name="BillNo"></param>
        /// <param name="FileId"></param>
        /// <param name="SendByte"></param>
        /// <returns></returns>
        public static object CreateUploadJson(string FileName, string FormId, bool IsLast, string InterId, string BillNo, string FileId, string SendByte)
        {
            JObject UploadJson = new JObject();
            UploadJson.Add("FileName", FileName);
            UploadJson.Add("FormId", FormId);
            UploadJson.Add("IsLast", IsLast.ToString());
            UploadJson.Add("InterId", InterId);
            UploadJson.Add("BillNo", BillNo);
            UploadJson.Add("AliasFileName", FileName);
            UploadJson.Add("FileId", FileId);
            UploadJson.Add("SendByte", SendByte);
            return UploadJson;
        }

        /// <summary>
        /// JSON串操作(保存、提交、审核)返回错误信息
        /// </summary>
        /// <param name="ReturnMsg">操作(保存、提交、审核)返回的Json信息</param>
        /// <returns></returns>
        public static string GetErrMsg(JObject ReturnMsg)
        {
            string ErrMsg = "";
            JArray jsonArray = ReturnMsg["Result"]["ResponseStatus"]["Errors"] as JArray;
            for (int i = 0; i < jsonArray.Count; i++)
            {
                if (ErrMsg == "")
                    ErrMsg = "字段：" + jsonArray[i]["FieldName"].Value<string>()
                           + " 错误信息：" + jsonArray[i]["Message"].Value<string>();
                else
                    ErrMsg = ErrMsg + "\r\n" + "字段：" + jsonArray[i]["FieldName"].Value<string>()
                           + " 错误信息：" + jsonArray[i]["Message"].Value<string>();
            }
            return ErrMsg;
        }
    }
}
